2 cap[i][j] = Capacidad de la arista (i, j).
3 prev[i] = Predecesor del nodo i en un camino de aumentación.
5 int cap
[MAXN
+1][MAXN
+1], prev
[MAXN
+1];
7 vector
<int> g
[MAXN
+1]; //Vecinos de cada nodo.
8 inline void link(int u
, int v
, int c
)
9 { cap
[u
][v
] = c
; g
[u
].push_back(v
), g
[v
].push_back(u
); }
11 Notar que link crea las aristas (u, v) && (v, u) en el grafo
12 g. Esto es necesario porque el algoritmo de Edmonds-Karp
13 necesita mirar el "back-edge" (j, i) que se crea al bombear
14 flujo a través de (i, j). Sin embargo, no modifica
15 cap[v][u], porque se asume que el grafo es dirigido. Si es
16 no-dirigido, hacer cap[u][v] = cap[v][u] = c.
23 Mantener la red residual, donde residual[i][j] = cuánto
24 flujo extra puedo inyectar a través de la arista (i, j).
26 Si empujo k unidades de i a j, entonces residual[i][j] -= k
27 y residual[j][i] += k (Puedo "desempujar" las k unidades de
30 Se puede modificar para que no utilice extra memoria en la
31 tabla residual, sino que modifique directamente la tabla
35 int residual
[MAXN
+1][MAXN
+1];
36 int fordFulkerson(int n
, int s
, int t
){
37 memcpy(residual
, cap
, sizeof cap
);
41 fill(prev
, prev
+n
, -1);
44 while (q
.size() && prev
[t
] == -1){
47 vector
<int> &out
= g
[u
];
48 for (int k
= 0, m
= out
.size(); k
<m
; ++k
){
50 if (v
!= s
&& prev
[v
] == -1 && residual
[u
][v
] > 0)
51 prev
[v
] = u
, q
.push(v
);
55 if (prev
[t
] == -1) break;
57 int bottleneck
= INT_MAX
;
58 for (int v
= t
, u
= prev
[v
]; u
!= -1; v
= u
, u
= prev
[v
]){
59 bottleneck
= min(bottleneck
, residual
[u
][v
]);
61 for (int v
= t
, u
= prev
[v
]; u
!= -1; v
= u
, u
= prev
[v
]){
62 residual
[u
][v
] -= bottleneck
;
63 residual
[v
][u
] += bottleneck
;
75 Mantener la red de flujos, donde flow[i][j] = Flujo que,
76 err, fluye de i a j. Notar que flow[i][j] puede ser
77 negativo. Si esto pasa, es lo equivalente a decir que i
78 "absorbe" flujo de j, o lo que es lo mismo, que hay flujo
81 En cualquier momento se cumple la propiedad de skew
82 symmetry, es decir, flow[i][j] = -flow[j][i]. El flujo neto
83 de i a j es entonces flow[i][j].
86 int flow
[MAXN
+1][MAXN
+1];
87 int fordFulkerson(int n
, int s
, int t
){
88 //memset(flow, 0, sizeof flow);
89 for (int i
=0; i
<n
; ++i
) fill(flow
[i
], flow
[i
]+n
, 0);
92 fill(prev
, prev
+n
, -1);
95 while (q
.size() && prev
[t
] == -1){
98 vector
<int> &out
= g
[u
];
99 for (int k
= 0, m
= out
.size(); k
<m
; ++k
){
101 if (v
!= s
&& prev
[v
] == -1 && cap
[u
][v
] > flow
[u
][v
])
102 prev
[v
] = u
, q
.push(v
);
106 if (prev
[t
] == -1) break;
108 int bottleneck
= INT_MAX
;
109 for (int v
= t
, u
= prev
[v
]; u
!= -1; v
= u
, u
= prev
[v
]){
110 bottleneck
= min(bottleneck
, cap
[u
][v
] - flow
[u
][v
]);
112 for (int v
= t
, u
= prev
[v
]; u
!= -1; v
= u
, u
= prev
[v
]){
113 flow
[u
][v
] += bottleneck
;
114 flow
[v
][u
] = -flow
[u
][v
];